package server

import (
	"database/sql"
	"encoding/json"
	"errors"
	"fmt"
	"strconv"
	"strings"
)

type WeiXinLogin struct {
	SessionKey string `json:"session_key"`
	OpenId     string `json:"openid"`
}

//请求微信后台登录url
func req_weixin_login(js_code string) (*WeiXinLogin, error) {
	param := make(map[string]string)
	param["appid"] = WXAPPId
	param["secret"] = WXAPPSecret
	param["js_code"] = js_code
	param["grant_type"] = "authorization_code"
	resp, err := HttpGet("https://api.weixin.qq.com/sns/jscode2session", param)
	if err != nil {
		return nil, err
	}

	var loginData WeiXinLogin //微信平台信息
	err = json.Unmarshal(resp, &loginData)
	if err != nil {
		return nil, err
	}

	return &loginData, nil
}

//检查family中是否包含一些人, 只要有一个不包含，就返回false
func api_family_contain_person(tx *sql.Tx, family int64, persons []int64) (bool, error) {
	if 0 == family {
		return false, nil
	}
	if len(persons) == 0 {
		return true, nil
	}
	persons = RemoveDupInt64(persons) //删除重复的
	sql := fmt.Sprintf("select count(*) from tb_family_member where family_id = ? and person_id in (%s)", strings.Join(ArrInt64ToArrStr(persons), ","))
	var count int
	err := tx.QueryRow(sql, family).Scan(&count)
	if err != nil {
		return false, err
	}
	return len(persons) == count, nil
}

//检查两个人是否同属于某一个家族
func api_two_person_in_one_family(tx *sql.Tx, person1 int64, person2 int64) (bool, error) {
	rows, err := tx.Query("select 1 where exists (select * from tb_family_member a, tb_family_member b where a.family_id = b.family_id and a.person_id = ? and b.person_id = ?)", person1, person2)
	if err != nil {
		return false, PrefixError("查询两个人是否属于同一家族", err)
	}
	result, err := SelectResultFromRows(rows)
	if err != nil || len(result) == 0 {
		return false, nil
	} else {
		return true, nil
	}
}

//翻译delta数据中的图片，将图片ID更新为图片url
func DeltaUnInterpretImage(delta_content string, article_image_map map[int64]string) (string, error) {
	type OneDelta struct {
		Text  interface{} `json:"insert"`
		Attrs interface{} `json:"attributes"`
	}
	type DeltaContent struct {
		Ops []OneDelta `json:"ops"`
	}
	var delta DeltaContent
	err := json.Unmarshal([]byte(delta_content), &delta)
	if err != nil {
		return "", err
	}

	for i := 0; i < len(delta.Ops); i++ {
		m, ok := delta.Ops[i].Text.(map[string]interface{})
		if ok {
			val, ok := m["image"]
			if ok {
				imagestr, _ := val.(string)
				imageId, err := strconv.ParseInt(imagestr, 10, 64)
				if err != nil {
					return "", err
				}
				image_name, ok := article_image_map[imageId]
				if ok {
					image_url := fmt.Sprintf("http://"+GlobalConf.ServerIP+":8088/%s", image_name)
					m["image"] = image_url
					delta.Ops[i].Text = m
				} else {
					return "", errors.New("图片id匹配失败")
				}
			}
		}
	}

	json, err := json.Marshal(delta)
	if err != nil {
		return "", err
	}
	return string(json), nil
}

//翻译delta数据中的图片，将图片url更新为图片ID
//其中pic_exist_cache: 图片名字 -> 图片id  ;  pic_local_cache: ops下标 -> 图片id
//注意内部会删除匹配到的pic_exist_cache图片，函数返回后剩下的pic_exist_cache键值对就是需要删除的图片。
func DeltaInterpretImage(delta_content string, pic_exist_cache map[string]int64, pic_local_cache map[int64]int64) (string, error) {
	type OneDelta struct {
		Text  interface{} `json:"insert"`
		Attrs interface{} `json:"attributes"`
	}
	type DeltaContent struct {
		Ops []OneDelta `json:"ops"`
	}
	var delta DeltaContent
	err := json.Unmarshal([]byte(delta_content), &delta)
	if err != nil {
		return "", err
	}

	for i := 0; i < len(delta.Ops); i++ {
		m, ok := delta.Ops[i].Text.(map[string]interface{})
		if ok {
			val, ok := m["image"]
			if ok {
				imagestr, _ := val.(string)
				imageId, ok := pic_local_cache[int64(i)]
				if ok {
					//本地图片
					m["image"] = strconv.FormatInt(imageId, 10)
					delta.Ops[i].Text = m
					continue
				}

				imageName := GetFileNameFromUrl(imagestr) //图片名字
				imageId, ok = pic_exist_cache[imageName]
				if ok {
					//已存在的图片
					delete(pic_exist_cache, imageName)
					m["image"] = strconv.FormatInt(imageId, 10)
					delta.Ops[i].Text = m
					continue
				}

				return "", errors.New("delta图片匹配失败:" + imagestr)
			}
		}
	}

	json, err := json.Marshal(delta)
	if err != nil {
		return "", err
	}
	return string(json), nil
}

//从delta中获取提示text
func DeltaTipText(delta_content string, max_len int) (string, error) {
	type OneDelta struct {
		Text  interface{} `json:"insert"`
		Attrs interface{} `json:"attributes"`
	}
	type DeltaContent struct {
		Ops []OneDelta `json:"ops"`
	}
	var delta DeltaContent
	err := json.Unmarshal([]byte(delta_content), &delta)
	if err != nil {
		return "", err
	}

	var result string
	for i := 0; i < len(delta.Ops); i++ {
		text, ok := delta.Ops[i].Text.(string)
		if ok {
			result += strings.ReplaceAll(text, "\n", "  ")
			if len(result) >= max_len {
				break
			}
		}
	}

	//截取max_len长度
	runes := []rune(result)
	result = string(runes[:MinInt(len(runes), max_len)])
	return result, nil
}
